package paleGoldenRod.client;


import java.util.ArrayList;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.rpc.ServiceDefTarget;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.KeyboardListener;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TabPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Timer;
/*
import com.mapitz.gwt.googleMaps.client.GLatLng;
import com.mapitz.gwt.googleMaps.client.GMap2;
import com.mapitz.gwt.googleMaps.client.GMap2Widget;
import com.mapitz.gwt.googleMaps.client.GMap2EventManager;
import com.mapitz.gwt.googleMaps.client.GMap2EventMoveListener;
//*/
import com.mapitz.gwt.googleMaps.client.*;
//import

/**
 * Entry point classes define <code>onModuleLoad()</code>.
 */
public class ThinkMap implements EntryPoint {
	
	final GMarkerEventManager markerEventManager = GMarkerEventManager.getInstance();
	GMap2 gmaps;
	ArrayList gameNames = new ArrayList();
	
	static int bt = 'a';
	static int sg = 'a';
    //String brainTuner = "<script src=\"http://gmodules.com/ig/ifr?url=http://elliot.lee.googlepages.com/brain.xml&amp;up_score=100&amp;synd=open&amp;w=320&amp;h=300&amp;title=Brain+Tuner&amp;border=%23ffffff%7C3px%2C1px+solid+%23999999&amp;output=js\"></script>";
	//String brainTuner = "<iframe width=\"320\" scrolling=\"\" height=\"300\" frameborder=\"0\" style=\"display: block;\" src=\"http://gmodules.com/ig/ifr?url=http://elliot.lee.googlepages.com/brain.xml&up_score=100&synd=open&w=320&h=300&title=Brain+Tuner&border=%23ffffff%7C3px%2C1px+solid+%23999999&source=http%3A%2F%2Fgmodules.com%2Fig%2Fcreator%3Fsynd%3Dopen%26url%3Dhttp%253A%2F%2Felliot.lee.googlepages.com%2Fbrain.xml%26pt%3D%2526context%253Dd%2526synd%253Dig%2526lang%253Den%2526.lang%253Den%2526country%253Dus%2526.country%253Dus%2526start%253D0%2526num%253D1%2526objs%253DVgU%252CLkc%252CAr%252CUe%252CK6j%252C2tz%26sn%3DVgU%26lang%3Den\"/>";
	HTML infoBox;
	String gameType = "Brain Tuner";
	
	String brainTuner = "<iframe width=\"320\" scrolling=\"\" height=\"300\" frameborder=\"0\" style=\"display: block;\" src=\"http://gmodules.com/ig/ifr?url=http://elliot.lee.googlepages.com/braintuner.xml\"/>";
	String wordHunter = "<iframe width=\"320\" scrolling=\"\" height=\"300\" frameborder=\"0\" style=\"display: block;\" src=\"http://gmodules.com/ig/ifr?url=http://elliot.lee.googlepages.com/boggle.xml\"/>";
	String scroogle = "<iframe width=\"320\" scrolling=\"\" height=\"300\" frameborder=\"0\" style=\"display: block;\" src=\"http://192.168.1.104:8080/paleGoldenRod.ScroogleGUI/ScroogleGUI.html\"/>";

	private final class JoinCallback implements AsyncCallback {
		int instance;
		public JoinCallback(int length) {
			instance=length-1;
		}

		public void onFailure(Throwable caught) {
		      // TODO Auto-generated method stub
		      
		 }

		public void onSuccess(Object result) {
		      String suggestions = (String) result;
				//String printedSuggestions = new String();
				//label[0][0].setText("Received: " + suggestions);
		 }
/*
		private int min(int length, int length2) {
			if(length>length2)
				return length2;
			else
				return length;
		}
		//*/
	}

	
	private final class NgramCallback implements AsyncCallback {
		int instance;
		public NgramCallback(int length) {
			instance=length-1;
		}

		public void onFailure(Throwable caught) {
		      // TODO Auto-generated method stub
		      
		 }

		public void onSuccess(Object result) {
		      //String suggestions = (String) result;
				//String printedSuggestions = new String();
				//label[0][0].setText("Success!");
		 }
/*
		private int min(int length, int length2) {
			if(length>length2)
				return length2;
			else
				return length;
		}
		//*/
	}

    private ThinkMapServiceAsync getThinkMapService(){
        ThinkMapServiceAsync thinkMapService = (ThinkMapServiceAsync) 
		             GWT.create(ThinkMapService.class);
        ServiceDefTarget endpoint = (ServiceDefTarget) thinkMapService;
        String moduleRelativeUrl = GWT.getModuleBaseURL() + "messagingService";
        endpoint.setServiceEntryPoint(moduleRelativeUrl);
        return thinkMapService;
   } 
    int timerDelay = 500;
    public void updateMarkers() {
    	
		// hack: Update the markers
        ThinkMapServiceAsync thinkMapService = getThinkMapService();
        AsyncCallback callback = new AsyncCallback() {
			public void onFailure(Throwable caught) {
				GWT.log("onFailure", caught);
			    // Create a new timer that calls updateMarkers()
			    Timer t = new Timer() {
			      public void run() {
			        updateMarkers();
			      }
			    };
			    t.schedule(timerDelay);
			}
			public void onSuccess(Object result) {
				//GWT.log("onSuccess", null);
				try {
					ArrayList gms = (ArrayList) result;
					GameMarker gm;

					for (int i = 0; i < gms.size(); i++) {
						//GWT.log("gms.get(" + i + ") of " + gms.size(), null);
						gm = (GameMarker) gms.get(i);
						//GWT.log("!gameNames.contains()", null);
						if (!gameNames.contains(gm.game)) {
							//GWT.log("createNewMarker", null);
							createNewMarker(gm.lat, gm.lng,
									gm.creator, gm.game, gm.gType);
							gameNames.add(gm.game);
							GWT.log("gm.game " + gm.game, null);

							if (new String("Brain Tuner").indexOf(gm.game) >= 0) {
								bt++;
								GWT.log("Added bt", null);
							} else {
								sg++;
							}
						}
					}
					//GWT.log("chart:"+bt+" "+sg, null);
					infoBox.setHTML("<div id='infoBox'>There are currently " +
							gms.size() + " active games. You are creating <b>" +
							gameType + "</b> games <i>(click to change)</i>.<br><img src='http://chart.apis.google.com/chart?cht=p3&chd=s:" + bt + sg + "&chs=400x100&chl=Brain%20Tuner|Scroogle|WordHunter%20Xtreme' width='400' height='100'></div>");
				} catch (Exception e) {
					GWT.log("Caught exception", e);
				}
			    // Create a new timer that calls updateMarkers()
			    Timer t = new Timer() {
			      public void run() {
			        updateMarkers();
			      }
			    };
			    t.schedule(timerDelay);
			}
        };
        thinkMapService.getMarkers(callback);
    }
    
	//private TextBox textbox = new TextBox();
	//private Label label[][] = new Label[3][5];
	//private TextBox statusText = new TextBox();
	//private TextBox nickText = new TextBox();
	//private Button nickButton = new Button("Login");
	String nickname;
	private static int gameCount = 0;
	public void onModuleLoad() {
		//DOM.getElementById("statusText").innerHTML = "";
		//RootPanel.get("statusText").add(statusText);
		//RootPanel.get("statusText").add(nickText);
		//RootPanel.get("statusText").add(nickButton);
		//RootPanel.get().add(new BlindedPopup("Hello", true));
		//BlindedPopup bp = 
		new BlindedPopup("Nickname:", true, this);
	    //Alternative method: Setting your own center value and zoom in
	    //the constructor
	    //GMap2Widget mapWidget = new GMap2Widget("300", "300",
	    //new GLatLng(37.4419, -122.1419), 13);

	    //Retrieve the GMap2 object and start manipulating your map
		//Element mapSlot = ;
		GMap3Widget mapWidget = new GMap3Widget(DOM.getElementById("mapSlot"), new GLatLng(34.021898,-118.285031), 15);//mapSlot);
		//RootPanel.get("mapSlot").add(mapWidget);
		//mapWidget.setElement(DOM.getElementById("mapSlot"));
		gmaps = mapWidget.getGmap();
		gmaps.addControl(GControl.GLargeMapControl());
		gmaps.addControl(GControl.GMapTypeControl());
		
		/*
	    TabPanel tp = new TabPanel();
	    tp.add(new HTML("Foo"), "foo");
	    tp.add(new HTML("Bar"), "bar");
	    tp.add(new HTML("Baz"), "baz");

	    // Show the 'bar' tab initially.
	    tp.selectTab(1);
	    
	    tp.setWidth("300");
	    tp.setHeight("200");
*/
		infoBox = new HTML("<div id='infoBox'>Welcome to ThinkMap!</div>");
		infoBox.addClickListener(new ClickListener() {
			public void onClick(Widget sender) {
				if (gameType == "Brain Tuner") {
					gameType = "WordHunter Xtreme";
				} else {
					gameType = "Brain Tuner";
				}
			}
		});
		gmaps.addControl(new GControl(infoBox, new GControlPosition(GControlAnchor.G_ANCHOR_BOTTOM_RIGHT(), new GSize(5,5))));
		//DOM.getElementById("mapSlot")
		//Widget hello = new Widget();
		//HTML html = new HTML();
		//html.
		//hello.
	    //GLatLng center = gmaps.getCenter();

	    //gmaps.openInfoWindowHtml(center, msg);
	    
	    //gmaps.checkResize();
	    
	    GMap2EventManager eventManager = GMap2EventManager.getInstance();

	    eventManager.addOnMoveStartListener(gmaps, new GMap2EventMoveListener() {
	    	public void onMoveStart(GMap2 map) {
	    		GWT.log("onMoveStart", null);
	    	}

                    public void onMoveEnd(GMap2 map) {
                    	// Something to happen when the move ends
                    }

                    public void onMove(GMap2 map) {
                    	// Something happens
                    }
        		});



//7.) Example of adding a map marker event listeners
    
   /*
    GMarker gmarker = new GMarker(center);
    markerEventManager.addOnInfoWindowOpenListener(gmarker, new GMarkerEventInfoWindowListener()
                {
                                public void onInfoWindowOpen(GMarker
marker)
                                {

                                	statusText.setText("Info window open");
                                }

                                public void onInfoWindowClose(GMarker
marker)
                                {
                                }
                }
    );
*/
    //gmaps.addOverlay(gmarker);
    
    eventManager.addOnClickListener(gmaps, new GMap2EventClickListener() {
    	public void onClick(GMap2 map, GOverlay overlay, GLatLng point) {
	    	//GWT.log("onClick " + point.toString(), null); 
	    	// Add a GMarker to that point
	    	GMarker gmarker = createNewMarker(point.lat(), point.lng(), nickname, gameType + " Game " + (++gameCount), gameType);
	    	// Now save this marker on the server
	        ThinkMapServiceAsync thinkMapService = getThinkMapService();
	        AsyncCallback callback = new AsyncCallback() {
				public void onFailure(Throwable caught) {
					GWT.log("onFailure", caught);
				}
				public void onSuccess(Object result) {
					GWT.log("onSuccess", null);

				}
	        };
	        String gn = gameType + " Game " + (++gameCount) + " by " + nickname;
	        GameMarker gameMarker = new GameMarker(gmarker, nickname, gn, gameType);
	        thinkMapService.sendMarker(gameMarker, callback);
	        gameNames.add(gn);
	        if (gameType == "Brain Tuner") {
	        	bt++;
	        } else {
	        	sg++;
	        }
	        //thinkMapService.sendDouble(new Double(gmarker.getPoint().lat()), callback);
    	}

    });
/*
    markerEventManager.addOnDragEndListener(gmarker, new
GMarkerEventDragListener()
                {
                                public void onDragEnd(GMarker marker)
                                {
                                	statusText.setText("On drag end");
                                }

                                public void onDragStart(GMarker
marker)

                                {
                                }
                }
    );
*/
//8.) Using the geocoder

    GGeocodeAdvancedResultListener gAResult = new GGeocodeAdvancedResultListener()
    {
                public void onSuccess(GGeocodeResult result)
                {
                        //Do someting with the results
                }

                public void onFail(GGeoStatusCode status, String address)
                {
                                     //Do something on the fail
                }
    };

    GFactualGeocodeCache cache = new GFactualGeocodeCache();
    GClientGeocoder geocoder = new GClientGeocoder(cache);
    geocoder.getLocations("4807 Fern Hollow, Austin, TX, 78731",
gAResult); 
	    
	    
		/*
		textbox.setText("");
		textbox.setWidth("40em");
		textbox.setReadOnly(false);
		textbox.setEnabled(true);
		textbox.addKeyboardListener(new KeyboardListener(){

			public void onKeyDown(Widget sender, char keyCode, int modifiers) {
				// TODO Auto-generated method stub
				
			}

			public void onKeyPress(Widget sender, char keyCode, int modifiers) {
				// TODO Auto-generated method stub
				
			}

			public void onKeyUp(Widget sender, char keyCode, int modifiers) {
				// TODO Auto-generated method stub
				if(keyCode==13){
					commit();
				}
				else if(keyCode==32){
					update();
				}
				//handleChange();
			}

			
		});

		// Assume that the host HTML has elements defined whose
		// IDs are "slot1", "slot2".  In a real app, you probably would not want
		// to hard-code IDs.  Instead, you could, for example, search for all 
		// elements with a particular CSS class and replace them with widgets.
		//
		RootPanel.get("top").add(textbox);
		for(int j=0;j<label.length;j++){
			for(int i=0;i<label[j].length;i++){
				label[j][i] = new Label();
				RootPanel.get("word"+(j+1)+""+(i+1)).add(label[j][i]);
			}
		}
		//*/
	}
	protected void update() {
		// TODO Auto-generated method stub
        ThinkMapServiceAsync thinkMapService = this.getThinkMapService();
        AsyncCallback callback = new JoinCallback(0);
        thinkMapService.getString(callback);
	}
	protected void commit() {
		// TODO Auto-generated method stub
        ThinkMapServiceAsync thinkMapService = this.getThinkMapService();
        AsyncCallback callback = new NgramCallback(0);
        //thinkMapService.sendString(textbox.getText(), callback);
	}
	
	protected void msgNickname(String n) {
		nickname = n;
		GWT.log("Received msgNickname " + n, null);
		updateMarkers();
	}
	
	public GMarker createNewMarker(double lat, double lng, String creator, final String game, final String gType) {
    	GMarker gmarker = new GMarker(new GLatLng(lat, lng));
        markerEventManager.addOnClickListener(gmarker, new GMarkerEventClickListener() {
    		public void onClick(GMarker marker) {
        		GWT.log("GMarkerEventClickListener " + marker.getPoint(), null);
    			//gmaps.openInfoWindowHtml(marker.getPoint(), game);
        		//GWT.log("brainTuner " + brainTuner, null);
        		GInfoWindowOptions giwo = new GInfoWindowOptions();
        		giwo.setMaxWidth(320);
        		if (gType == "Brain Tuner") {
        			gmaps.openInfoWindowHtml(marker.getPoint(), brainTuner, giwo);
        		} else {
        			gmaps.openInfoWindowHtml(marker.getPoint(), wordHunter, giwo);
        		}
    		}
    		public void onDblClick(GMarker marker) { }
        });
    	gmaps.addOverlay(gmarker);
    	return gmarker;
	}
}
